package com.topsun.framework.common.mybatis.plugins.page;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.topsun.framework.common.core.util.ServletUtil;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @author pipi
 */
public class Page {
    private static final ThreadLocal<LinkedList<PageInfo>> LOCAL_PAGE = new ThreadLocal<>();
    /**
     * 当前记录起始索引
     */
    public static final String PAGE_NUM = "pageNum";

    /**
     * 每页显示记录数
     */
    public static final String PAGE_SIZE = "pageSize";

    /**
     * 排序列
     */
    public static final String ORDER_BY_COLUMN = "orderByColumn";

    /**
     * 默认升序，传true降序
     */
    public static final String IS_DESC = "isDesc";

    /**
     * 分页参数合理化
     */
    public static final String REASONABLE = "reasonable";

    private static PageInfo getPageInfo() {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setCurrent(Convert.toLong(ServletUtil.getParameter(PAGE_NUM), 1L));
        pageInfo.setSize(Convert.toLong(ServletUtil.getParameter(PAGE_SIZE), 10L));
        String orderColumn = ServletUtil.getParameter(ORDER_BY_COLUMN);
        if (StrUtil.isNotBlank(orderColumn)) {
            OrderItem orderItem = new OrderItem();
            orderItem.setColumn(orderColumn);
            orderItem.setAsc(!Convert.toBool(ServletUtil.getParameter(IS_DESC), Boolean.FALSE));
            pageInfo.addOrder(orderItem);
        }
        return pageInfo;
    }


    /**
     * 分页查询 使用该方法，select实现方法中必须优先查询分页
     *
     * @param page
     * @param limit
     * @param select
     * @param <E>
     * @return
     */
    public static <E> Pagination<E> query(int page, int limit, ISelect<E> select) {
        return query(select, new PageInfo(page, limit));
    }

    /**
     * 分页查询 使用该方法，select实现方法中必须优先查询分页
     *
     * @param select
     * @param page
     * @param limit
     * @param <E>
     * @return
     */
    public static <E> Pagination<E> query(ISelect<E> select, int page, int limit) {
        return query(select, new PageInfo(page, limit));
    }

    /**
     * 分页查询 使用该方法，select实现方法中必须优先查询分页
     *
     * @param select
     * @param pageInfo
     * @param <E>
     * @return
     */
    public static <E> Pagination<E> query(ISelect<E> select, PageInfo pageInfo) {
        LinkedList<PageInfo> pageInfoList = LOCAL_PAGE.get();
        if (Objects.isNull(pageInfoList)) {
            LOCAL_PAGE.set(pageInfoList = CollUtil.newLinkedList());
        }
        pageInfoList.addFirst(pageInfo);
        try {
            List<E> list = select.select();
            return new Pagination<>(pageInfo, list);
        } finally {
            remove();
        }
    }

    public static <E> Pagination<E> query(ISelect<E> select) {
        PageInfo pageInfo = getPageInfo();
        return query(select, pageInfo);
    }

    public static void remove() {
        LinkedList<PageInfo> pageInfos = LOCAL_PAGE.get();
        if (CollUtil.isEmpty(pageInfos)) {
            LOCAL_PAGE.remove();
            return;
        }
        pageInfos.removeFirst();

    }

    public static PageInfo get() {
        LinkedList<PageInfo> pageInfos = LOCAL_PAGE.get();
        if (CollUtil.isEmpty(pageInfos)) {
            return null;
        }
        return pageInfos.getFirst();
    }

    public interface ISelect<E> {
        List<E> select();
    }
}